package cn.acewill.lrz.thread;

/**
 * volatile关键字
 * 1、表示变量对所有线程可见，即：单个线程修改，其他线程立即知晓。
 *    因为volatile对所有线程可见，所以对volatile变量所有的写操作都能立即反应的其他线程中，换句话说：
 *    “volatile的变量在各个线程中是一致的，所以基于volatile变量的运算在并发下是安全的。”  该理解是错误的，如下代码所示：
 *    当存在线程让步时，A线程持有volatile变量的值进行计算时让步，B线程持有改volatile变量进行计算，B计算后值改变，之后A线程再执行，由于A线程进行了让步，存在已经处于计算中的状态，该状态时volatile变量值无法再次获取最新数据。
 *    故上述结论是错误的。
 * 2、禁止指令重排序优化
 */
public class VolatileTest {
    private static volatile  int idx = 0;
    public static void increase(){
        idx++;
    }
    private static final int THREAD_COUNT=20;
    public static void main(String[] args) {
        Thread threadArr[] = new Thread[THREAD_COUNT];
        for(int i=0;i<threadArr.length;i++) {
            threadArr[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j=0;j<10000;j++) {
                        increase();
                    }
                }
            });
            threadArr[i].start();
        }
        //等到所有线程都运行结束
        while (Thread.activeCount()>1)
            /*
            yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”，从而让其它具有相同优先级的等待线程获取执行权；但是，并不能保
            证在当前线程调用yield()之后，其它具有相同优先级的线程就一定能获得执行权；也有可能是当前线程又进入到“运行状态”继续运行！
            */
            Thread.yield();
        System.out.println(idx);
    }
}
